package com.ruoyi.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.system.entity.*;
import com.ruoyi.system.mapper.*;
import com.ruoyi.system.service.QnnQuestionnaireService;
import com.ruoyi.system.vo.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.HashMap;
import java.util.Map;

import com.ruoyi.system.dto.QuestionnaireQueryDTO;

import java.util.stream.Collectors;

@Service
public class QnnQuestionnaireServiceImpl extends ServiceImpl<QnnQuestionnaireMapper, QnnQuestionnaire>
        implements QnnQuestionnaireService {

    @Autowired
    private QnnQuestionnaireMapper questionnaireMapper;

    @Autowired
    private QnnQuestionMapper questionMapper;

    @Autowired
    private QnnOptionMapper optionMapper;

    @Autowired
    private QnnAnswerSheetMapper answerSheetMapper;

    @Autowired
    private QnnAnswerMapper answerMapper;

    @Autowired
    private QnnQuestionnaireScopeMapper questionnaireScopeMapper;

    @Autowired
    private QnnQuestionnaireModuleMapper questionnaireModuleMapper;

    @Override
    public long countDeliveryUsers(Long questionnaireId) {
        // scopeType=0(公开)时投放量可按全量客户或0；这里定义为：若scopeType=0，则返回0；若=1，返回范围表数量
        QnnQuestionnaire questionnaire = questionnaireMapper.selectById(questionnaireId);
        if (questionnaire == null) return 0L;
        if (questionnaire.getScopeType() == null || questionnaire.getScopeType() == 0) {
            return 0L;
        }
        return questionnaireScopeMapper.selectCount(new LambdaQueryWrapper<QnnQuestionnaireScope>()
                .eq(QnnQuestionnaireScope::getQuestionnaireId, questionnaireId));
    }

    @Override
    public long countValidSubmits(Long questionnaireId) {
        // 简化：所有答卷均视为有效（后续可增加状态或校验）
        return answerSheetMapper.selectCount(new LambdaQueryWrapper<QnnAnswerSheet>()
                .eq(QnnAnswerSheet::getQuestionnaireId, questionnaireId));
    }

    @Override
    public List<QnnQuestionnaire> listAvailableForUserByModule(String userId, Integer module, Integer offset, Integer limit) {
        // 1) 找到指定模块下的问卷ID
        List<Long> moduleQids = questionnaireModuleMapper.selectList(new LambdaQueryWrapper<QnnQuestionnaireModule>()
                        .eq(QnnQuestionnaireModule::getModule, module))
                .stream().map(QnnQuestionnaireModule::getQuestionnaireId).distinct().collect(Collectors.toList());
        if (moduleQids.isEmpty()) {
            return java.util.Collections.emptyList();
        }
        // 2) 预拉取当前用户在范围表内的问卷ID
        List<Long> inScopeQids = questionnaireScopeMapper.selectList(new LambdaQueryWrapper<QnnQuestionnaireScope>()
                        .eq(QnnQuestionnaireScope::getUserId, userId))
                .stream().map(QnnQuestionnaireScope::getQuestionnaireId).distinct().collect(Collectors.toList());

        // 3) 过滤：已发布 + 时间有效 + in module + (scopeType=0 或 在范围内)
        LambdaQueryWrapper<QnnQuestionnaire> qw = new LambdaQueryWrapper<>();
        qw.in(QnnQuestionnaire::getId, moduleQids)
                .eq(QnnQuestionnaire::getStatus, 1)
                .and(w -> w.isNull(QnnQuestionnaire::getStartTime).or().le(QnnQuestionnaire::getStartTime, LocalDateTime.now()))
                .and(w -> w.isNull(QnnQuestionnaire::getEndTime).or().ge(QnnQuestionnaire::getEndTime, LocalDateTime.now()))
                .and(w -> w.eq(QnnQuestionnaire::getScopeType, 0)
                        .or().in(!inScopeQids.isEmpty(), QnnQuestionnaire::getId, inScopeQids))
                .orderByDesc(QnnQuestionnaire::getUpdateTime)
                .last("limit " + limit + " offset " + offset);
        return questionnaireMapper.selectList(qw);
    }

    @Override
    public Map<Integer, Long> summaryAvailableByModules(String userId, List<Integer> modules) {
        Map<Integer, Long> result = new HashMap<>();
        if (modules == null || modules.isEmpty()) return result;
        for (Integer m : modules) {
            // 统计逻辑与列表相同，但只取数量
            List<Long> moduleQids = questionnaireModuleMapper.selectList(new LambdaQueryWrapper<QnnQuestionnaireModule>()
                            .eq(QnnQuestionnaireModule::getModule, m))
                    .stream().map(QnnQuestionnaireModule::getQuestionnaireId).distinct().collect(Collectors.toList());
            if (moduleQids.isEmpty()) {
                result.put(m, 0L);
                continue;
            }
            List<Long> inScopeQids = questionnaireScopeMapper.selectList(new LambdaQueryWrapper<QnnQuestionnaireScope>()
                            .eq(QnnQuestionnaireScope::getUserId, userId))
                    .stream().map(QnnQuestionnaireScope::getQuestionnaireId).distinct().collect(Collectors.toList());
            LambdaQueryWrapper<QnnQuestionnaire> qw = new LambdaQueryWrapper<>();
            qw.in(QnnQuestionnaire::getId, moduleQids)
                    .eq(QnnQuestionnaire::getStatus, 1)
                    .and(w -> w.isNull(QnnQuestionnaire::getStartTime).or().le(QnnQuestionnaire::getStartTime, LocalDateTime.now()))
                    .and(w -> w.isNull(QnnQuestionnaire::getEndTime).or().ge(QnnQuestionnaire::getEndTime, LocalDateTime.now()))
                    .and(w -> w.eq(QnnQuestionnaire::getScopeType, 0)
                            .or().in(!inScopeQids.isEmpty(), QnnQuestionnaire::getId, inScopeQids));
            result.put(m, questionnaireMapper.selectCount(qw));
        }
        return result;
    }

    @Override
    public List<QnnQuestionnaire> queryAdminList(QuestionnaireQueryDTO dto) {
        // 可选模块过滤：先取该模块的问卷ID集合
        List<Long> moduleQids = null;
        if (dto.getModule() != null) {
            moduleQids = questionnaireModuleMapper.selectList(new LambdaQueryWrapper<QnnQuestionnaireModule>()
                            .eq(QnnQuestionnaireModule::getModule, dto.getModule()))
                    .stream().map(QnnQuestionnaireModule::getQuestionnaireId).distinct().collect(Collectors.toList());
            if (moduleQids.isEmpty()) {
                return Collections.emptyList();
            }
        }

        LambdaQueryWrapper<QnnQuestionnaire> qw = buildAdminQueryWrapper(dto, moduleQids);
        int offset = Math.max(0, (dto.getPage() - 1) * dto.getSize());
        qw.orderByDesc(QnnQuestionnaire::getUpdateTime).last("limit " + dto.getSize() + " offset " + offset);
        return questionnaireMapper.selectList(qw);
    }

    @Override
    public long queryAdminCount(QuestionnaireQueryDTO dto) {
        List<Long> moduleQids = null;
        if (dto.getModule() != null) {
            moduleQids = questionnaireModuleMapper.selectList(new LambdaQueryWrapper<QnnQuestionnaireModule>()
                            .eq(QnnQuestionnaireModule::getModule, dto.getModule()))
                    .stream().map(QnnQuestionnaireModule::getQuestionnaireId).distinct().collect(Collectors.toList());
            if (moduleQids.isEmpty()) {
                return 0L;
            }
        }
        LambdaQueryWrapper<QnnQuestionnaire> qw = buildAdminQueryWrapper(dto, moduleQids);
        return questionnaireMapper.selectCount(qw);
    }

    private LambdaQueryWrapper<QnnQuestionnaire> buildAdminQueryWrapper(QuestionnaireQueryDTO dto, List<Long> moduleQids) {
        LambdaQueryWrapper<QnnQuestionnaire> qw = new LambdaQueryWrapper<>();
        if (moduleQids != null) {
            qw.in(QnnQuestionnaire::getId, moduleQids);
        }
        if (dto.getTitle() != null && !dto.getTitle().isEmpty()) {
            qw.like(QnnQuestionnaire::getTitle, dto.getTitle());
        }
        if (dto.getStatus() != null) {
            qw.eq(QnnQuestionnaire::getStatus, dto.getStatus());
        }
        if (dto.getCreatorId() != null) {
            qw.eq(QnnQuestionnaire::getCreatorId, dto.getCreatorId());
        }
        if (dto.getStartTime() != null && !dto.getStartTime().isEmpty()) {
            qw.ge(QnnQuestionnaire::getStartTime, LocalDateTime.parse(dto.getStartTime().replace(" ", "T")));
        }
        if (dto.getEndTime() != null && !dto.getEndTime().isEmpty()) {
            qw.ge(QnnQuestionnaire::getEndTime, LocalDateTime.parse(dto.getEndTime().replace(" ", "T")));
        }
        if (dto.getScopeType() != null) {
            qw.eq(QnnQuestionnaire::getScopeType, dto.getScopeType());
        }
        return qw;
    }

    @Override
    @Transactional
    public Long createQuestionnaire(QuestionnaireVO questionnaireVO) {
        // 保存问卷基本信息
        QnnQuestionnaire questionnaire = new QnnQuestionnaire();
        BeanUtils.copyProperties(questionnaireVO, questionnaire);
        questionnaire.setStatus(0); // 默认为草稿状态
        questionnaireMapper.insert(questionnaire);

        // 保存问题和选项
        saveQuestionsAndOptions(questionnaire.getId(), questionnaireVO.getQuestions());

        // 保存投放范围（指定客户）
        if (questionnaireVO.getScopeType() != null && questionnaireVO.getScopeType() == 1 && questionnaireVO.getScopeUserIds() != null) {
            if (!questionnaireVO.getScopeUserIds().isEmpty()) {
                for (String userId : questionnaireVO.getScopeUserIds()) {
                    QnnQuestionnaireScope scope = new QnnQuestionnaireScope();
                    scope.setQuestionnaireId(questionnaire.getId());
                    scope.setUserId(userId);
                    questionnaireScopeMapper.insert(scope);
                }
            }
        }

        // 保存投放模块
        if (questionnaireVO.getModules() != null && !questionnaireVO.getModules().isEmpty()) {
            for (Integer module : questionnaireVO.getModules()) {
                QnnQuestionnaireModule mm = new QnnQuestionnaireModule();
                mm.setQuestionnaireId(questionnaire.getId());
                mm.setModule(module);
                questionnaireModuleMapper.insert(mm);
            }
        }

        return questionnaire.getId();
    }

    @Override
    @Transactional
    public boolean updateQuestionnaire(QuestionnaireVO questionnaireVO) {
        // 更新问卷基本信息
        QnnQuestionnaire questionnaire = new QnnQuestionnaire();
        BeanUtils.copyProperties(questionnaireVO, questionnaire);
        questionnaireMapper.updateById(questionnaire);

        // 删除原有问题和选项
        Long questionnaireId = questionnaireVO.getId();
        List<QnnQuestion> oldQuestions = questionMapper.selectList(
                new LambdaQueryWrapper<QnnQuestion>()
                        .eq(QnnQuestion::getQuestionnaireId, questionnaireId)
        );
        for (QnnQuestion question : oldQuestions) {
            optionMapper.delete(new QueryWrapper<QnnOption>().eq("question_id", question.getId()));
            questionMapper.deleteById(question.getId());
        }

        // 保存新的问题和选项
        saveQuestionsAndOptions(questionnaireId, questionnaireVO.getQuestions());

        // 重置并保存投放范围
        questionnaireScopeMapper.delete(new LambdaQueryWrapper<QnnQuestionnaireScope>()
                .eq(QnnQuestionnaireScope::getQuestionnaireId, questionnaireId));
        if (questionnaireVO.getScopeType() != null && questionnaireVO.getScopeType() == 1 && questionnaireVO.getScopeUserIds() != null) {
            if (!questionnaireVO.getScopeUserIds().isEmpty()) {
                for (String userId : questionnaireVO.getScopeUserIds()) {
                    QnnQuestionnaireScope scope = new QnnQuestionnaireScope();
                    scope.setQuestionnaireId(questionnaireId);
                    scope.setUserId(userId);
                    questionnaireScopeMapper.insert(scope);
                }
            }
        }

        // 重置并保存投放模块
        questionnaireModuleMapper.delete(new LambdaQueryWrapper<QnnQuestionnaireModule>()
                .eq(QnnQuestionnaireModule::getQuestionnaireId, questionnaireId));
        if (questionnaireVO.getModules() != null && !questionnaireVO.getModules().isEmpty()) {
            for (Integer module : questionnaireVO.getModules()) {
                QnnQuestionnaireModule mm = new QnnQuestionnaireModule();
                mm.setQuestionnaireId(questionnaireId);
                mm.setModule(module);
                questionnaireModuleMapper.insert(mm);
            }
        }

        return true;
    }

    @Override
    public QnnQuestionnaire getQuestionnaireDetail(Long id) {
        QnnQuestionnaire q = questionnaireMapper.selectById(id);
        if (q == null) {
            return null;
        }
        // 组装问题与选项
        List<QnnQuestion> questions = questionMapper.selectList(new LambdaQueryWrapper<QnnQuestion>()
                .eq(QnnQuestion::getQuestionnaireId, id)
                .orderByAsc(QnnQuestion::getSortNum));
        if (questions != null && !questions.isEmpty()) {
            List<Long> qIds = questions.stream().map(QnnQuestion::getId).collect(Collectors.toList());
            List<QnnOption> options = optionMapper.selectList(new LambdaQueryWrapper<QnnOption>()
                    .in(QnnOption::getQuestionId, qIds)
                    .orderByAsc(QnnOption::getSortNum));
            Map<Long, List<QnnOption>> map = options.stream()
                    .collect(Collectors.groupingBy(QnnOption::getQuestionId));
            for (QnnQuestion qu : questions) {
                qu.setOptions(map.getOrDefault(qu.getId(), Collections.emptyList()));
            }
        }
        List<QnnQuestionnaireModule> qnnQuestionnaireModules = questionnaireModuleMapper.selectList(new LambdaQueryWrapper<QnnQuestionnaireModule>()
                .eq(QnnQuestionnaireModule::getQuestionnaireId, id));
        if (!qnnQuestionnaireModules.isEmpty()) {
            List<Integer> modules = qnnQuestionnaireModules.stream()
                    .map(QnnQuestionnaireModule::getModule)
                    .collect(Collectors.toList());
            q.setModules(modules);
        }
        List<QnnQuestionnaireScope> qnnQuestionnaireScopes = questionnaireScopeMapper.selectList(new LambdaQueryWrapper<QnnQuestionnaireScope>()
                .eq(QnnQuestionnaireScope::getQuestionnaireId, id));
        if (!qnnQuestionnaireScopes.isEmpty()) {
            List<String> scopeUserIds = qnnQuestionnaireScopes.stream()
                    .map(QnnQuestionnaireScope::getUserId)
                    .collect(Collectors.toList());
            // 设置指定客户ID集合
            q.setScopeUserIds(scopeUserIds);
        }
        q.setQuestions(questions);
        return q;
    }

    @Override
    @Transactional
    public boolean publishQuestionnaire(Long id) {
        QnnQuestionnaire questionnaire = new QnnQuestionnaire();
        questionnaire.setId(id);
        questionnaire.setStatus(1); // 已发布
        questionnaire.setStartTime(LocalDateTime.now());
        return questionnaireMapper.updateById(questionnaire) > 0;
    }

    @Override
    @Transactional
    public boolean endQuestionnaire(Long id) {
        QnnQuestionnaire questionnaire = new QnnQuestionnaire();
        questionnaire.setId(id);
        questionnaire.setStatus(2); // 已结束状态
        questionnaire.setEndTime(LocalDateTime.now());
        return questionnaireMapper.updateById(questionnaire) > 0;
    }

    @Override
    @Transactional
    public Long submitAnswer(SubmitAnswerVO submitAnswerVO) {
        // 检查问卷状态是否为发布中
        QnnQuestionnaire questionnaire = questionnaireMapper.selectById(submitAnswerVO.getQuestionnaireId());
        if (questionnaire == null || questionnaire.getStatus() != 1) {
            throw new RuntimeException("问卷不存在或未发布");
        }

        // 限制答卷时长（如果配置了）
        if (questionnaire.getDurationMinutes() != null && questionnaire.getDurationMinutes() > 0 && submitAnswerVO.getClientStartTime() != null) {
            LocalDateTime clientStart = LocalDateTime.parse(submitAnswerVO.getClientStartTime());
            LocalDateTime localDateTime = clientStart.plusMinutes(questionnaire.getDurationMinutes());
            LocalDateTime now = LocalDateTime.now();
            if (localDateTime.isBefore(now)) {
                throw new RuntimeException("已超过答题时长限制");
            }
        }

        // 创建答卷记录
        QnnAnswerSheet answerSheet = new QnnAnswerSheet();
        answerSheet.setQuestionnaireId(submitAnswerVO.getQuestionnaireId());
        answerSheet.setUserId(submitAnswerVO.getUserId());
        if (submitAnswerVO.getClientStartTime() != null) {
            try {
                answerSheet.setClientStartTime(LocalDateTime.parse(submitAnswerVO.getClientStartTime()));
            } catch (Exception ignore) {
            }
        }
        answerSheet.setSubmitTime(LocalDateTime.now());
        answerSheetMapper.insert(answerSheet);

        // 保存答案
        List<AnswerVO> answers = submitAnswerVO.getAnswers();
        if (answers != null && !answers.isEmpty()) {
            for (AnswerVO answerVO : answers) {
                QnnAnswer answer = new QnnAnswer();
                answer.setAnswerSheetId(answerSheet.getId());
                answer.setQuestionId(answerVO.getQuestionId());
                answer.setContent(answerVO.getContent());
                answerMapper.insert(answer);
            }
        }

        return answerSheet.getId();
    }

    /**
     * 保存问题和选项
     */
    private void saveQuestionsAndOptions(Long questionnaireId, List<QuestionVO> questionVOs) {
        if (questionVOs == null || questionVOs.isEmpty()) {
            return;
        }

        for (QuestionVO questionVO : questionVOs) {
            // 保存问题
            QnnQuestion question = new QnnQuestion();
            BeanUtils.copyProperties(questionVO, question);
            question.setQuestionnaireId(questionnaireId);
            questionMapper.insert(question);

            // 保存选项（如果有）
            if (questionVO.getOptions() != null && !questionVO.getOptions().isEmpty()) {
                for (OptionVO optionVO : questionVO.getOptions()) {
                    QnnOption option = new QnnOption();
                    BeanUtils.copyProperties(optionVO, option);
                    option.setQuestionId(question.getId());
                    optionMapper.insert(option);
                }
            }
        }
    }
}
